package com.autumn.mybatis.mapper;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.UpdateProvider;

import com.autumn.mybatis.criterion.ICriteriaSection;
import com.autumn.mybatis.criterion.IQuerySection;
import com.autumn.mybatis.criterion.ISpecifyQuerySection;
import com.autumn.mybatis.criterion.ISpecifyUpdateSection;
import com.autumn.mybatis.criterion.LockModeEnum;

/**
 * 实体映射
 *
 * @author 杨昌国
 *         <p>
 *         2017-10-11 17:45:28
 */
public interface IEntityMapper<TEntity> extends IMapper {

	/**
	 * 段参数名称
	 */
	public final static String ARG_NAME_SECTION = "section";

	/**
	 * 锁模式参数名称
	 */
	public final static String ARG_NAME_LOCK_MODE = "lockMode";

	/**
	 * 键参数名称
	 */
	public final static String ARG_NAME_KEY = "key";
	
	/**
	 * 列表参数名称
	 */
	public final static String ARG_NAME_LIST = "list";

	/*
	 * 下面常量的名称必须与自身函数名称相同，并且与EntityMapperProvider对应的函数名称也必须相同，不能使用重载函数
	 */

	/**
	 * 插入
	 */
	public final static String INSERT = "insert";
	/**
	 * 批量插入
	 */
	public final static String BATCH_INSERT = "batchInsert";
	/**
	 * 全部更新
	 */
	public final static String UPDATE = "update";
	/**
	 * 非 null 更新
	 */
	public final static String UPDATE_NOT_NULL = "updateNotNull";
	/**
	 * 指定部份更新
	 */
	public final static String UPDATE_BY_SPECIFY = "updateBySpecify";
	/**
	 * 基于主键删除
	 */
	public final static String DELETE_BY_PRIMARY_KEY = "deleteByPrimaryKey";
	/**
	 * 基于条件删除
	 */
	public final static String DELETE_BY_WHERE = "deleteByWhere";

	/**
	 * 删除所有
	 */
	public final static String DELETE_BY_ALL = "deleteByAll";

	/**
	 * 快速清除
	 */
	public final static String TRUNCATE_BY_TABLE = "truncateTable";

	/**
	 * 基于主键查询
	 */
	public final static String GET = "get";
	/**
	 * 基于主键加锁查询
	 */
	public final static String GET_BY_LOCK = "getByLock";
	/**
	 * 查符合条件的首条件
	 */
	public final static String SELECT_FIRST = "selectFirst";
	/**
	 * 查符合条件的首条件
	 */
	public final static String SELECT_BY_SPECIFY_FIRST = "selectBySpecifyFirst";
	/**
	 * 指定查询
	 */
	public final static String SELECT_BY_SPECIFY = "selectBySpecify";
	/**
	 * 查询所有
	 */
	public final static String SELECT_ALL = "selectAll";
	/**
	 * 查询所有(锁)
	 */
	public final static String SELECT_ALL_BY_LOCK = "selectAllByLock";
	/**
	 * 查询得到list集合
	 */
	public final static String SELECT_LIST = "selectList";
	/**
	 * 查询所有记录数
	 */
	public final static String COUNT = "count";
	/**
	 * 统计所有记录数(锁)
	 */
	public final static String COUNT_BY_LOCK = "countByLock";
	/**
	 * 根据条件查询记录数
	 */
	public final static String COUNT_BY_WHERE = "countByWhere";

	/**
	 * 插入(如果配置自增主键，则返回自增id)
	 *
	 * @param entity
	 *            实体
	 * @return 返回影响行数
	 */
	@InsertProvider(type = EntityMapperProvider.class, method = INSERT)
	int insert(TEntity entity);

	/**
	 * 批量插入(数据库主键id为自增，不会返回自增id值，插入数据条数由调用者控制，至少需要一条记录)
	 *
	 * @param entity
	 * @return
	 */
	@InsertProvider(type = EntityMapperProvider.class, method = BATCH_INSERT)
	int batchInsert(@Param(ARG_NAME_LIST) List<TEntity> entity);

	/**
	 * 截断表数据(快速清除,不支持事务)
	 * 
	 * @return
	 */
	@DeleteProvider(type = EntityMapperProvider.class, method = TRUNCATE_BY_TABLE)
	void truncateTable();

	/**
	 * 删除所有数据
	 * 
	 * @return
	 */
	@DeleteProvider(type = EntityMapperProvider.class, method = DELETE_BY_ALL)
	int deleteByAll();

	/**
	 * 基于主键删除
	 *
	 * @param keyValue
	 *            主键
	 * @return 返回影响行数
	 */
	@DeleteProvider(type = EntityMapperProvider.class, method = DELETE_BY_PRIMARY_KEY)
	int deleteByPrimaryKey(Object keyValue);

	/**
	 * 基于条件删除
	 *
	 * @param criteriaSection
	 *            条件段
	 * @return 返回影响行数
	 */
	@DeleteProvider(type = EntityMapperProvider.class, method = DELETE_BY_WHERE)
	int deleteByWhere(@Param(ARG_NAME_SECTION) ICriteriaSection criteriaSection);

	/**
	 * 基于主键进行更新，包括null值
	 *
	 * @param entity
	 *            实体
	 * @return 返回影响行数
	 */
	@UpdateProvider(type = EntityMapperProvider.class, method = UPDATE)
	int update(TEntity entity);

	/**
	 * 基于主键进行更新，跳过 null 值
	 *
	 * @param entity
	 *            实体
	 * @return 返回影响行数
	 */
	@UpdateProvider(type = EntityMapperProvider.class, method = UPDATE_NOT_NULL)
	int updateNotNull(TEntity entity);

	/**
	 * 修改指定字段
	 *
	 * @param updateSection
	 *            指定更新
	 * @return
	 */
	@UpdateProvider(type = EntityMapperProvider.class, method = UPDATE_BY_SPECIFY)
	int updateBySpecify(@Param(ARG_NAME_SECTION) ISpecifyUpdateSection updateSection);

	/**
	 * 基于主键查询
	 *
	 * @param keyValue
	 *            主键值
	 * @return 返回 查询的实体
	 */
	@SelectProvider(type = EntityMapperProvider.class, method = GET)
	TEntity get(Object keyValue);

	/**
	 * 基于主键查询
	 *
	 * @param keyValue
	 *            主键值
	 * @param lockMode
	 *            锁模式
	 * @return 返回 查询的实体
	 */
	@SelectProvider(type = EntityMapperProvider.class, method = GET_BY_LOCK)
	TEntity getByLock(@Param(ARG_NAME_KEY) Object keyValue, @Param(ARG_NAME_LOCK_MODE) LockModeEnum lockMode);

	/**
	 * 查询实体首条记录
	 *
	 * @param querySection
	 *            查询段
	 * @return
	 */
	@SelectProvider(type = EntityMapperProvider.class, method = SELECT_FIRST)
	TEntity selectFirst(@Param(ARG_NAME_SECTION) IQuerySection querySection);

	/**
	 * 查符合条件的首条件
	 *
	 * @param querySection
	 *            指定查询段
	 * @return
	 */
	@SelectProvider(type = EntityMapperProvider.class, method = SELECT_BY_SPECIFY_FIRST)
	Map<String, Object> selectBySpecifyFirst(@Param(ARG_NAME_SECTION) ISpecifyQuerySection querySection);

	/**
	 * 指定查询
	 *
	 * @param querySection
	 *            指定查询段
	 * @return
	 */
	@SelectProvider(type = EntityMapperProvider.class, method = SELECT_BY_SPECIFY)
	List<Map<String, Object>> selectBySpecify(@Param(ARG_NAME_SECTION) ISpecifyQuerySection querySection);

	/**
	 * 查询所有
	 *
	 * @return 返回
	 */
	@SelectProvider(type = EntityMapperProvider.class, method = SELECT_ALL)
	List<TEntity> selectAll();

	/**
	 * 查询所有(锁)
	 * 
	 * @param lockMode
	 * @return
	 */
	@SelectProvider(type = EntityMapperProvider.class, method = SELECT_ALL_BY_LOCK)
	List<TEntity> selectAllByLock(@Param(ARG_NAME_LOCK_MODE) LockModeEnum lockMode);

	/**
	 * 查询list集合
	 *
	 * @param querySection
	 *            查询段
	 * @return
	 */
	@SelectProvider(type = EntityMapperProvider.class, method = SELECT_LIST)
	List<TEntity> selectList(@Param(ARG_NAME_SECTION) IQuerySection querySection);

	/**
	 * 查询所有记录数
	 *
	 * @return 返回
	 */
	@SelectProvider(type = EntityMapperProvider.class, method = COUNT)
	int count();

	/**
	 * 统计所有记录数(锁)
	 * 
	 * @param lockMode
	 * @return
	 */
	@SelectProvider(type = EntityMapperProvider.class, method = COUNT_BY_LOCK)
	int countByLock(@Param(ARG_NAME_LOCK_MODE) LockModeEnum lockMode);

	/**
	 * 根据条件查询记录数
	 *
	 * @param criteriaSection
	 *            条件段
	 * @return
	 */
	@SelectProvider(type = EntityMapperProvider.class, method = COUNT_BY_WHERE)
	int countByWhere(@Param(ARG_NAME_SECTION) ICriteriaSection criteriaSection);
}
